<!DOCTYPE HTML>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../resources/gesture-util.js"></script>
<script src="../../../virtual/percent-based-scrolling/resources/percent-based-util.js"></script>
<style>
#scrollableDiv {
  width: 200px;
  height: 200px;
  overflow: scroll;
}

#innerDiv {
  width: 400px;
  height: 400px;
}
</style>

<body style="margin:0">
<div id="scrollableDiv">
  <div id="innerDiv">
  </div>
</div>
</body>

<script>
if (window.internals)
  internals.runtimeFlags.overscrollCustomizationEnabled = true;

var scrolling_div = document.getElementById('scrollableDiv');
var rect = scrolling_div.getBoundingClientRect();
var x = rect.left + rect.width / 2;
var y = rect.top + rect.height / 2;

const pixelsToScroll = 600;
const { x: pixelsToScrollX, y: pixelsToScrollY } = calculatePixelsToScroll(
  scrolling_div, pixelsToScroll, pixelsToScroll
);

var horizontal_scrollend_arrived = false;
var vertical_scrollend_arrived = false;
function onHorizontalScrollEnd(event) {
  assert_false(event.cancelable);
  assert_false(event.bubbles);
  horizontal_scrollend_arrived = true;
}
function onVerticalScrollEnd(event) {
  assert_false(event.cancelable);
  assert_false(event.bubbles);
  vertical_scrollend_arrived = true;
}
scrolling_div.addEventListener("scrollend", onHorizontalScrollEnd);
scrolling_div.addEventListener("scrollend", onVerticalScrollEnd);

async function test_scrollend_event_fire(source_device,
    precise_scrolling_delta) {
  horizontal_scrollend_arrived = false;
  vertical_scrollend_arrived = false;
  scrolling_div.scrollTo(0, 0);
  await waitForCompositorCommit();

  // Do a horizontal scroll and wait for scrollend event.
  await smoothScroll(
    pixelsToScrollX, x, y, source_device, "right", SPEED_INSTANT,
    precise_scrolling_delta
  );
  await waitFor(() => { return horizontal_scrollend_arrived; },
      'Scroller did not receive scrollend event after horizontal scroll.');
  await waitForAnimationEndTimeBased(() => { return scrolling_div.scrollLeft });
  assert_equals(scrolling_div.scrollWidth - scrolling_div.scrollLeft,
              scrolling_div.clientWidth);

  // Do a vertical scroll and wait for scrollend event.
  await smoothScroll(
    pixelsToScrollY, x, y, source_device, "down", SPEED_INSTANT,
    precise_scrolling_delta
  );
  await waitFor(() => { return vertical_scrollend_arrived; },
      'Scroller did not receive scrollend event after vertical scroll.');
  await waitForAnimationEndTimeBased(() => { return scrolling_div.scrollTop });
  assert_equals(scrolling_div.scrollHeight - scrolling_div.scrollTop,
              scrolling_div.clientHeight);
}

promise_test (async (t) => {
  // Make sure that no scrollend event is sent to document.
  document.addEventListener("scrollend",
      t.unreached_func("Document got unexpected scrollend event."));
  return test_scrollend_event_fire(GestureSourceType.TOUCH_INPUT);
}, 'Tests that the scrolled element gets scrollend event at the end of touch scrolling.');
promise_test (async (t) => {
  // Make sure that no scrollend event is sent to document.
  document.addEventListener("scrollend",
      t.unreached_func("Document got unexpected scrollend event."));
  return test_scrollend_event_fire(GestureSourceType.MOUSE_INPUT, true);
}, 'Tests that the scrolled element gets scrollend event at the end of ' +
   'non-animated wheel scrolling.');
promise_test (async (t) => {
  // Make sure that no scrollend event is sent to document.
  document.addEventListener("scrollend",
      t.unreached_func("Document got unexpected scrollend event."));
  return test_scrollend_event_fire(GestureSourceType.MOUSE_INPUT, false);
}, 'Tests that the scrolled element gets scrollend event at the end of ' +
   'animated wheel scrolling (smooth-scrolling).');
</script>
